package com.test.stuff;

import java.util.ArrayList;
import java.util.List;

public class MoneySplit{
	
	protected static Logger logger = new Logger(MoneySplit.class.getSimpleName());
	
	public static void main(String args[]) throws Exception{
		System.out.println("Hello world");
		testBasics();
//		testMethods();
//		testClasses();
	}
	
	public static void testBasics() throws Exception{
		logger.log("  ~~~~basics");
		testAccountBasic();
		testGroupBasic();
		testTransactionBasic();
	}
	
	public static void testMethods() throws Exception{
		logger.log("  ~~~~methods");
		testAccountMethod();
		testGroupMethod();
		testTransactionMethod();
	}
	
	public static void testClasses() throws Exception{
		logger.log(  "~~~classes");
		testAccount();
		testGroup();
		testTransaction();
	}
	
	public static void testAccount() throws Exception{
		logger.log("  ~~account");
		testAccountBasic();
		testAccountMethod();
	}
	
	public static void testGroup() throws Exception{
		logger.log("  #~~group");
		testGroupBasic();
		testGroupMethod();
	}
	
	public static void testTransaction() throws Exception{
		logger.log("  #~~transaction");
		testTransactionBasic();
		testTransactionMethod();
	}
	
	////////////////////////
	public static void testAccountBasic() throws Exception{
		int expectedErrors = 3;
		int currentErrors = 0;
		
		logger.log("  #~init account");
		String acctName1 = "Bob";
		String acctName2 = "John";
		String acctName3 = "Jane";
		String acctName4 = "";

		try{
			Account acct1__1 = new Account(acctName1, -1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		
		try{
			Account acct1_0 = new Account(acctName1, 0);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		
		Account acct1_1 = new Account(acctName1, 1);
		Account acct1_1b = new Account(acctName1, 1);
		Account acct2_1 = new Account(acctName2, 1);
		Account acct3_1 = new Account(acctName3, 1);
		try{
			Account acct4_1 = new Account(acctName4, 1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		
		Account acct1_2 = new Account(acctName1, 2);
		Account acct2_2 = new Account(acctName2, 2, 100);
		Account acct3_2 = new Account(acctName3, 2, -36);
		
		Account acct1_3 = new Account(acctName1, 3);
		Account acct2_3 = new Account(acctName2, 3);
		Account acct3_3 = new Account(acctName3, 3);
		
		logger.log("  ~toString()");
		logger.log(acct1_1);
		logger.log(acct1_1b);
		logger.log(acct2_1);
		logger.log(acct3_1);
		logger.log("  ~equals()");
		logger.log(acct1_1.equals(acct1_1b));
		logger.log(acct1_1.equals(acct2_1));
		logger.log(acct2_1.equals(acct3_1));
		logger.log("  ~getters");
		logger.log(acct1_2.getId()+", "+acct1_2.getName()+", "+acct1_2.getBalance());
		logger.log(acct2_2.getId()+", "+acct2_2.getName()+", "+acct2_2.getBalance());
		logger.log(acct3_2.getId()+", "+acct3_2.getName()+", "+acct3_2.getBalance());
		logger.log("  ~setters");
		acct1_3.setId(acct1_3.getId()+10);
		acct1_3.setName(acct1_3.getName()+"by");
		acct1_3.setBalance(acct1_3.getBalance()+1234);
		logger.log(acct1_3.getId()+", "+acct1_3.getName()+", "+acct1_3.getBalance());
		acct2_3.setId(acct2_3.getId()*100);
		acct2_3.setName(acct2_3.getName()+" Doe");
		acct2_3.setBalance(acct2_3.getBalance()+0.01);
		logger.log(acct2_3.getId()+", "+acct2_3.getName()+", "+acct2_3.getBalance());
		acct3_3.setId(acct3_3.getId()-10);
		acct3_3.setName("");
		acct3_3.setBalance(-1000.10);
		logger.log(acct3_3.getId()+", "+acct3_3.getName()+", "+acct3_3.getBalance());
		
		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## account basic ~fin");
		}
	}

	public static void testGroupBasic() throws Exception{
		int expectedErrors = 6;
		int currentErrors = 0;
		
		logger.log("  #~init group");
		String grp1_name = "Group1";
		String grp2_name = "Pair2";
		String grp3_name = "Tri";
		
		Account act1 = new Account("Uno", 1);
		Account act2 = new Account("Two", 2);
		Account act3 = new Account("Tree", 3);
		Account[] act_array = new Account[] { act1, act2, act3 };
		List<Account> act_list1 = new ArrayList();
		act_list1.add(act1);
		act_list1.add(act2);
		act_list1.add(act3);
		List<Account> act_list2 = new ArrayList();
		act_list2.add(act1);
		try{
			Group grp0_0 = new Group("", 1, new Account[] { act1 } );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Group grp0_1 = new Group(grp1_name, 0, new Account[] { act1 } );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Group grp0_2 = new Group(grp1_name, -1, new Account[] { act1 } );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Group grp0_3 = new Group(grp1_name, 1, (Account[]) null );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Group grp0_4 = new Group(grp1_name, 1, new Account[] { } );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Group grp0_5 = new Group(grp1_name, 1, new ArrayList() );
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		
		Group grp1 = new Group(grp1_name, 1,  act_array);
		Group grp1b = new Group(grp1_name, 1,  act_list1);
		Group grp2 = new Group(grp2_name, 2,  act_list1);
		Group grp3 = new Group(grp3_name, 3,  act_list2);
		logger.log("  ~toString()");
		logger.log(grp1);
		logger.log(grp2);
		logger.log(grp3);
		logger.log("  ~equals()");
		logger.log(grp1.equals(grp1b));
		logger.log(grp2.equals(grp3));
		logger.log("  ~getters");
		logger.log(grp1.getName()+", "+grp1.getId()+", "+grp1.getAccounts());
		logger.log(grp1b.getName()+", "+grp1b.getId()+", "+grp1b.getAccounts());
		logger.log(grp2.getName()+", "+grp2.getId()+", "+grp2.getAccounts());
		logger.log(grp3.getName()+", "+grp3.getId()+", "+grp3.getAccounts());
		logger.log("  ~setters");
		grp1.setName(grp1.getName()+"000");
		grp1.setId(-1000);
		grp1.setAccounts(new ArrayList());
		logger.log(grp1.getName()+", "+grp1.getId()+", "+grp1.getAccounts());
		grp1b.setName("");
		grp1b.setId(0);
		grp1b.setAccounts((Account[]) null);
		logger.log(grp1b.getName()+", "+grp1b.getId()+", "+grp1b.getAccounts());
		grp2.setName("Zapdos");
		grp2.setId(2000);
		grp2.setAccounts(act_list2);
		logger.log(grp2.getName()+", "+grp2.getId()+", "+grp2.getAccounts());
		grp3.setName(grp3.getName()+"-tip");
		grp3.setId(34567);
		grp3.setAccounts(act_array);
		logger.log(grp3.getName()+", "+grp3.getId()+", "+grp3.getAccounts());
		
		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## group basic ~fin");
		}
	}
	
	public static void testTransactionBasic() throws Exception{
		int expectedErrors = 5;
		int currentErrors = 0;
		
		logger.log("  #~init transaction");
		Account act1 = new Account("Bob", 1);
		Account act2 = new Account("Jane", 2);
		
		Group grp1 = new Group("Uno", 1, new Account[] { act1 } );
		Group grp2 = new Group("Pair", 2, new Account[] { act1, act2 } );
		
		try{
			Transaction trans0_0 = new Transaction(-1, 0, act1, grp1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Transaction trans0_1 = new Transaction(0, 0, act1, grp1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Transaction trans0_2 = new Transaction(1, 0, null, grp1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Transaction trans0_3 = new Transaction(1, 0, act1, null);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		try{
			Transaction trans0_4 = new Transaction(1, 0, act1, grp1, -1);
		}
		catch(Exception e){
			logger.log("an exception was thrown, but was expected... incrementing");
			currentErrors++;
		}
		
		Transaction trans1 = new Transaction(1, 0, act1, grp1, 1234);
		Transaction trans1b = new Transaction(1, 0, act1, grp1, 1234);
		Transaction trans2 = new Transaction(2, 10, act2, grp1);
		Transaction trans3 = new Transaction(3, 100, act2, grp2, 0);
		logger.log("  ~toString()");
		logger.log(trans1);
		logger.log(trans1b);
		logger.log(trans2);
		logger.log(trans3);
		logger.log("  ~equals()");
		logger.log(trans1.equals(trans1b));
		logger.log(trans2.equals(trans3));
		logger.log("  ~getters");
		logger.log(trans1.getId()+", "+trans1.getDate()+", "+trans1.getAccount()+", "+trans1.getGroup()+", "+trans1.getAmount());
		logger.log(trans1b.getId()+", "+trans1b.getDate()+", "+trans1b.getAccount()+", "+trans1b.getGroup()+", "+trans1b.getAmount());
		logger.log(trans2.getId()+", "+trans2.getDate()+", "+trans2.getAccount()+", "+trans2.getGroup()+", "+trans2.getAmount());
		logger.log(trans3.getId()+", "+trans3.getDate()+", "+trans3.getAccount()+", "+trans3.getGroup()+", "+trans3.getAmount());
		logger.log("  ~setters");
		trans1.setId(-1000);
		trans1.setDate(0);
		trans1.setAccount(act2);
		trans1.setGroup(grp2);
		trans1.setAmount(9999);
		logger.log(trans1.getId()+", "+trans1.getDate()+", "+trans1.getAccount()+", "+trans1.getGroup()+", "+trans1.getAmount());
		trans1b.setId(0);
		trans1b.setDate(-1);
		trans1b.setAccount(null);
		trans1b.setGroup(null);
		trans1b.setAmount(1);
		logger.log(trans1b.getId()+", "+trans1b.getDate()+", "+trans1b.getAccount()+", "+trans1b.getGroup()+", "+trans1b.getAmount());
		trans2.setId(22);
		trans2.setDate(12345);
		trans2.setAccount(act1);
		trans2.setGroup(grp2);
		trans2.setAmount(trans2.getAmount()*10);
		logger.log(trans2.getId()+", "+trans2.getDate()+", "+trans2.getAccount()+", "+trans2.getGroup()+", "+trans2.getAmount());
		trans3.setId(333);
		trans3.setDate(67890);
		trans3.setAccount(act1);
		trans3.setGroup(grp1);
		trans3.setAmount(trans3.getAmount()*-10);
		logger.log(trans3.getId()+", "+trans3.getDate()+", "+trans3.getAccount()+", "+trans3.getGroup()+", "+trans3.getAmount());

		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## transaction basic ~fin");
		}
	}
	
	public static void testAccountMethod() throws Exception{
		int expectedErrors = 0;
		int currentErrors = 0;
		
		logger.log("  #~method account");
		
		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## account method ~fin");
		}
	}
	
	public static void testGroupMethod() throws Exception{
		int expectedErrors = 0;
		int currentErrors = 0;
		
		logger.log("  #~method group");
		
		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## group method ~fin");
		}
	}
	
	public static void testTransactionMethod() throws Exception{
		int expectedErrors = 0;
		int currentErrors = 0;
		
		logger.log("  #~method transaction");
		
		logger.log("  ~expected errors: "+expectedErrors);
		logger.log("  ~current errors : "+currentErrors);
		if(currentErrors!=expectedErrors){
			logger.log("--> the expected errors != current errors");
			throw new Exception("the expected errors != current errors");
		}
		else{
			logger.log("  ## transaction method ~fin");
		}
	}
}